/*
* Copyright 2005-2008 Pulse Technologies. Tutti i diritti riservati.
*/
package org.obsidianrad.server;


import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import javax.servlet.ServletContext;

import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemManager;
import org.apache.commons.vfs.VFS;
import org.obsidianrad.server.web.WebServer;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.GenericWebApplicationContext;

/**
 * 
 * @author eliosh
 * @version $Rev: 75 $
 * @lastautorcommit $Author: eliosh $
 * @lastdatecommit $Date: 2010-01-25 16:49:30 +0100(lun, 25 gen 2010) $
 */
public class ObsidianRad {

	private WebServer server = null;
	
	protected String beanXmlServerDefinitionPath;
	protected String beanXmlModulesDefinitionPath;
	protected File webFolder;
	
	protected GenericWebApplicationContext cpSpringCtx;
	protected static Logger log = Logger.getLogger(ObsidianRad.class.getCanonicalName());

	/**
	 * Costruttore di default
	 */
	public ObsidianRad(String _beanXmlServerDefinitionPath, String _beanXmlModulesDefinitionPath, File _webFolder ){
		this.beanXmlModulesDefinitionPath = _beanXmlModulesDefinitionPath;
		this.beanXmlServerDefinitionPath = _beanXmlServerDefinitionPath;
		this.webFolder = _webFolder;
		
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
            	endApp();
            }
        });
	}
	
	public final void start() throws Exception{
		start(true);
	}
	
	public final void start(boolean withWebServer) throws Exception{
		
		List<String> lista = new ArrayList<String>();
		
		FileSystemManager fsManager = VFS.getManager();
		FileObject FO = fsManager.resolveFile( this.beanXmlServerDefinitionPath ); // "res:it/pulsetech/tsdnobs/server/conf/"

        // Read the bean definition file
        FileObject[] children = FO.getChildren();
        for ( int i = 0; i < children.length; i++ ) {
        	if(children[i].getName().getBaseName().contains(".beans.xml")){
        		log.fine("Caricato beanfile : " + children[i].getName().getBaseName());
        		lista.add(children[i].getName().toString());
        	}
        }

        // Read the module definition file
        FO = fsManager.resolveFile( this.beanXmlModulesDefinitionPath ); // "res:it/pulsetech/tsdnobs/modules/conf/services/"
        children = FO.getChildren();
        for ( int i = 0; i < children.length; i++ ) {
        	if(children[i].getName().getBaseName().contains(".xml")){
        		log.fine("Caricato beanfile : " + children[i].getName().getBaseName());
        		lista.add(children[i].getName().toString());
        	}
        }
  
        String[] beans = new String[lista.size()];
		lista.toArray(beans);
		
		// Create ApplicationContext
		ClassPathXmlApplicationContext cp1 = new ClassPathXmlApplicationContext(beans);

		// create a web application context and set cp1 as parent
		cpSpringCtx = new GenericWebApplicationContext();
		cpSpringCtx.setParent(cp1);

		// force a refresh, so we can load effectively all bean definitions
		cpSpringCtx.refresh();  
		if(withWebServer){
			startWebServer();
		}
	}

	
	private void startWebServer() throws Exception{

		// get ServletContext reference
		server = (WebServer) cpSpringCtx.getBean("webServer");
		server.setBasePath(webFolder);

		ServletContext context = server.getServletContext();
		
//		// Inseriamo nel servlet context i vari oggetti necessari al funzionamento
		context.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, cpSpringCtx);
		
		server.startServer();
	}
	
	
	/**
	 * Metodo necessario per chiudere l'applicazione 
	 * @throws Exception 
	 *
	 */
	private void endObsidian() throws Exception{
		if(server!=null){
			server.stopServer();
		}
	}

	/**
	 * Metodo necessario per chiudere l'applicazione 
	 *
	 */
	private final void endApp(){
        try {
        	endObsidian();
        	cpSpringCtx.close();
    		cpSpringCtx.destroy();
        } catch (Throwable e) {
            System.err.println(e);
        }
		log.info("application closed");
	}


	

}
